/*
 * Copyright (C) 2016 Facishare Technology Co., Ltd. All Rights Reserved.
 */
package com.wlh.animation.demo;

import com.wlh.animation.R;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;

/**
 * @author weilh
 *         <b>DATE</b> 2016/7/14.
 */
public class RectToCircleView extends View{

    private boolean mDoLoading = false;
    public RectToCircleView(Context context) {
        super(context);
    }

    public RectToCircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RectToCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private RectF mRectF;
    private float mRaw = 0;
    Paint paint = new Paint();

    Paint mFirstCirclePaint = new Paint();
    Paint mSecondCirclePaint = new Paint();
    Paint mLastCirclePaint = new Paint();
    int mCircleFirstColor = Color.WHITE;
    int mCircleSecondColor = Color.parseColor("#80ffffff");
    int mCircleLastColor = Color.parseColor("#33ffffff");

    {
        mFirstCirclePaint.setColor(mCircleFirstColor);
        mSecondCirclePaint.setColor(mCircleSecondColor);
        mLastCirclePaint.setColor(mCircleLastColor);
    }

    private int mStartColor = Color.parseColor("#fcb058");
    private int mEndColor = Color.parseColor("#7fc25d");

    {
        paint.setColor(mStartColor);
    }
    public void setColor(int color) {
        paint.setColor(color);
    }

    public void setCircleFirstColor(int color) {
        mFirstCirclePaint.setColor(color);
        invalidate();
    }

    public void setCircleSecondColor(int color) {
        mSecondCirclePaint.setColor(color);
        invalidate();
    }

    public void setCircleLastColor(int color) {
        mLastCirclePaint.setColor(color);
        invalidate();
    }

    Paint bitmapPaint = new Paint();
    Bitmap bitmap;
    {
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
    }

    boolean showBitmap = false;

    float bitmapScale;

    public void setBitmapScale(float scale) {
        this.bitmapScale = scale;
        invalidate();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mRectF == null) {
            mRectF = new RectF();
            mRectF.right = getWidth();
            mRectF.bottom = getHeight();
        }
        if (mDoLoading) {
            canvas.drawRoundRect(mRectF, mRaw, mRaw, paint);
            canvas.drawCircle(getWidth() / 2 - 40, getHeight() / 2, 10 , mFirstCirclePaint);
            canvas.drawCircle(getWidth() / 2, getHeight() /2, 10, mSecondCirclePaint);
            canvas.drawCircle(getWidth() / 2 + 40, getHeight() / 2, 10, mLastCirclePaint);
        } else {
            canvas.drawRoundRect(mRectF, mRaw, mRaw, paint);
        }
        if (showBitmap) {
            int bitmapWidth = (int) (bitmap.getWidth() * bitmapScale);
            int bitmapHeight = (int) (bitmap.getHeight() * bitmapScale);
            if (bitmapWidth > 0) {
                Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, (int) bitmapWidth, (int) bitmapHeight, true);
                canvas.drawBitmap(scaledBitmap, getWidth() / 2 - bitmapWidth / 2, (getHeight() - bitmapHeight) / 2,
                        bitmapPaint);
            }
        }
    }


    private AnimatorSet mLoadingAnimatorSet;
    private ValueAnimator first, second, last;
    public void startLoadingAnimation() {
        mDoLoading = true;
        showBitmap = false;
        mFirstCirclePaint.setColor(mCircleFirstColor);
        mSecondCirclePaint.setColor(mCircleSecondColor);
        mLastCirclePaint.setColor(mCircleLastColor);
        invalidate();

        first = ObjectAnimator.ofInt(this, "circleFirstColor",
                mCircleFirstColor,  mCircleSecondColor, mCircleLastColor, mCircleSecondColor, mCircleFirstColor);
        first.setEvaluator(new ArgbEvaluator());

        second = ObjectAnimator.ofInt(this, "circleSecondColor",
                mCircleSecondColor, mCircleFirstColor, mCircleSecondColor, mCircleLastColor, mCircleSecondColor);
        second.setEvaluator(new ArgbEvaluator());

        last = ObjectAnimator.ofInt(this, "circleLastColor",
                mCircleLastColor, mCircleSecondColor, mCircleFirstColor, mCircleSecondColor, mCircleLastColor);
        last.setEvaluator(new ArgbEvaluator());

        first.setRepeatCount(ValueAnimator.INFINITE);
        second.setRepeatCount(ValueAnimator.INFINITE);
        last.setRepeatCount(ValueAnimator.INFINITE);

        first.setDuration(2000);
        second.setDuration(2000);
        last.setDuration(2000);
        first.start();
        second.start();
        last.start();
//        mLoadingAnimatorSet = new AnimatorSet();
//        mLoadingAnimatorSet.playTogether(first, second, last);
//        mLoadingAnimatorSet.setDuration(2000);
//        mLoadingAnimatorSet.start();
    }

    public void endLoadingAnimation() {
        mDoLoading = false;
        showBitmap = false;
        first.cancel();
        second.cancel();
        last.cancel();
        invalidate();
    }

    public void startAnimation() {
        RectF startRectF = new RectF();
        startRectF.right = getWidth();
        startRectF.bottom = getHeight();

        RectF endRectF = new RectF();
        endRectF.left =  startRectF.left + (getWidth() - getHeight()) / 2;
        endRectF.right = endRectF.left + getHeight();
        endRectF.bottom = startRectF.top + getHeight();
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new MyTypeEvaluator(), startRectF, endRectF);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mRectF = (RectF) animation.getAnimatedValue();
                invalidate();
            }
        });

        ObjectAnimator rawAnimator = ObjectAnimator.ofFloat(this, "raw", 0, getHeight() / 2);
        ObjectAnimator colorAnimator = ObjectAnimator.ofInt(this, "color", mStartColor, mEndColor);
        colorAnimator.setEvaluator(new ArgbEvaluator());

        final AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(valueAnimator, rawAnimator, colorAnimator);
        animatorSet.setInterpolator(new AccelerateInterpolator());
        animatorSet.setDuration(400);
        animatorSet.start();

        postDelayed(new Runnable() {
            @Override
            public void run() {
                startShowImg();
            }
        }, 200);
        postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        startRevertAnimation();
                    }
                }, 1400);

    }

    public void setBitmapAlpha(int alpha) {
        bitmapPaint.setAlpha(alpha);
        invalidate();
    }

    public void startShowImg() {
        showBitmap = true;
        bitmapPaint.setAlpha(0xff);
        bitmapScale = 0;
        invalidate();
        ValueAnimator animator = ObjectAnimator.ofInt(this, "bitmapAlpha", 0, 0xff);
        ValueAnimator scaleAnimator = ObjectAnimator.ofFloat(this, "bitmapScale", 0, 1);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(scaleAnimator, animator);
        animatorSet.setDuration(500);
        animatorSet.start();
    }

    public void startRevertAnimation() {
        showBitmap = false;
        RectF startRectF = new RectF();
        startRectF.right = getWidth();
        startRectF.bottom = getHeight();

        RectF endRectF = new RectF();
        endRectF.left =  startRectF.left + (getWidth() - getHeight()) / 2;
        endRectF.right = endRectF.left + getHeight();
        endRectF.bottom = startRectF.top + getHeight();
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new MyTypeEvaluator(), endRectF, startRectF);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mRectF = (RectF) animation.getAnimatedValue();
                invalidate();
            }
        });

        ObjectAnimator rawAnimator = ObjectAnimator.ofFloat(this, "raw", getHeight() / 2, 0);
        ObjectAnimator colorAnimator = ObjectAnimator.ofInt(this, "color", mEndColor, mStartColor);
        colorAnimator.setEvaluator(new ArgbEvaluator());

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(valueAnimator, rawAnimator, colorAnimator);
        animatorSet.setInterpolator(new AccelerateInterpolator());
        animatorSet.setDuration(600);
        animatorSet.start();


    }


    public void setRaw(float raw) {
       this.mRaw = raw;
    }
    public class MyTypeEvaluator implements TypeEvaluator<RectF> {

        @Override
        public RectF evaluate(float fraction, RectF startValue, RectF endValue) {
            RectF result = new RectF();
            result.top = startValue.top;
            result.bottom = startValue.bottom;
            result.left = startValue.left + (endValue.left - startValue.left) * fraction;
            result.right = startValue.right - (startValue.right - endValue.right) * fraction;
            return result;
        }
    }
}
